/**
 * Copyright (c) 2019, ShangHai YTO Co., Ltd.
 * All right reserved.
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF YTO
 * CO., LTD.  THE CONTENTS OF THIS FILE MAY NOT BE DISCLOSED
 * TO THIRD PARTIES, COPIED OR DUPLICATED IN ANY FORM, IN WHOLE OR IN PART,
 * WITHOUT THE PRIOR WRITTEN PERMISSION OF YTO
 * CO., LTD.
 */
package org.sc.xl.easyexcel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;
import java.util.function.Predicate;

/**
 * @description: TODO 请在此添加描述
 * @reason: TODO ADD REASON(可选)
 * @author FXL
 *
 * @date 2024/10/19 17:40 
 * @since JDK 1.8
 */
public class CustomCellMergeHandler implements CellWriteHandler {


    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();
        if (curRowIndex > mergeRowIndex) {
            for (int columnIndex : mergeColumnIndex) {
                if (curColIndex == columnIndex) {
                    mergeRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }
        if (3 == curColIndex && curRowIndex >= 2 && curRowIndex < 68) {
            mergeCol(writeSheetHolder, cell, curRowIndex, curColIndex);
        }
        //第二页第一行，作为第二页总表头
        if (68 == curRowIndex && writeSheetHolder.getHead().size() - 1 == curColIndex) {
            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 1, curColIndex);
            writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
            cell.setCellValue("上海概况表");
        }
        //第二页第二行 -- 产品特征 -- 表头
        if (curRowIndex >= 69 && curRowIndex <= 73) {
            if (5 == curColIndex) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 4, curColIndex);
                writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
                if (curRowIndex == 69) {
                    writeSheetHolder.getSheet().getRow(curRowIndex).getCell(curColIndex).setCellValue("业务量占比");
                }
            }
            if (writeSheetHolder.getHead().size() - 1 == curColIndex) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 7, curColIndex);
                writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
                if (curRowIndex == 69) {
                    //下一行设置上一行表头
                    writeSheetHolder.getSheet().getRow(curRowIndex).getCell(curColIndex).setCellValue("主要产品");
                }
            }
        }
        //第二页 -- 基础规划 -- 表头
        if (curRowIndex == 74 && writeSheetHolder.getHead().size() - 1 == curColIndex) {
            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 4, curColIndex);
            writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
            writeSheetHolder.getSheet().getRow(curRowIndex).getCell(curColIndex).setCellValue("经营情况");
        }
        if (curRowIndex >= 75 && curRowIndex <= 76) {
            if (writeSheetHolder.getHead().size() - 1 == curColIndex) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 4, curColIndex);
                writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
            }
        }
        if (curRowIndex == 77) {
            if (writeSheetHolder.getHead().size() - 1 == curColIndex) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 4, curColIndex);
                writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
            }
        }
        if (curRowIndex >= 78 && writeSheetHolder.getHead().size() - 1 == curColIndex) {
            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, 3, curColIndex);
            writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
        }

    }


    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public CustomCellMergeHandler(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    private void mergeRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        //获取当前行的当前列的数据和上一行的当前列列数据，通过上一行数据是否相同进行合并
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();

        // 比较当前行的第一列的单元格与上一行是否相同，相同合并当前单元格与上一行
        if (curData.equals(preData)) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一个单元格已经被合并，则先移出原有的合并单元，再重新添加合并单元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一个单元格未被合并，则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }

    private void mergeCol(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        //当前单元格中数据
        String curData = String.valueOf(cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue());
        //获取当前单元格的左面一个单元格
        Cell leftCell = cell.getSheet().getRow(curRowIndex).getCell(curColIndex - 1);
        //获取当前单元格的左面一个单元格中的数据
        String leftData = String.valueOf(leftCell.getCellTypeEnum() == CellType.STRING ? leftCell.getStringCellValue() : leftCell.getNumericCellValue());
        // 将当前单元格数据与左侧一个单元格数据比较
        if (StringUtils.isEmpty(curData)) {
            //获取当前sheet页
            Sheet sheet = writeSheetHolder.getSheet();
            //得到所有的合并单元格
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            //是否合并
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                if (cellRangeAddr.isInRange(curRowIndex, curColIndex - 1)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastColumn(curColIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若左侧一个单元格未被合并，则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex, curRowIndex, curColIndex - 1, curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }


    @Override
    public int order() {
        return 2;
    }
}
